package com.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.common.constant.MailConstant;
import com.common.constant.SharesConstan;
import com.common.utils.DateUtil;
import com.common.utils.MeUtils;
import com.common.utils.Result;
import com.common.utils.StringUtil;
import com.entity.*;
import com.mapper.HintSharesMapper;
import com.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.unit.DataUnit;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wty
 * @since 2021-11-19
 */
@Service
public class HintSharesServiceImpl extends ServiceImpl<HintSharesMapper, HintShares>
        implements HintSharesService {

    @Autowired
    private CodeCjlService codeCjlService;

    @Autowired
    private SharesGdChangeService sharesGdChangeService ;

    @Autowired
    private HintSharesService hintSharesService;

    @Autowired
    private SharesDataService sharesDataService;

    @Autowired
    private HintNumService hintNumService;

    @Autowired
    private SharesDetailService sharesDetailService;

    @Override
    public void doHint(List<HintShares> hintCodes) {
        if(CollectionUtils.isEmpty(hintCodes)){
            return;
        }

        for (HintShares hintCode : hintCodes) {
            String code = hintCode.getCode();
            String imgcode=""   ;
            if(code.contains("sz")){
                imgcode= "0."+code.substring(2);
            }else{
                imgcode= "1."+code.substring(2);
            }
            //k线图
            hintCode.setSrcf("http://webquotepic.eastmoney.com/GetPic.aspx?nid="+imgcode+"&imageType=r");
            hintCode.setSrc5("http://webquoteklinepic.eastmoney.com/GetPic.aspx?nid="+imgcode+"&UnitWidth=-6&imageType=KXL&EF=&Formula=RSI&AT=1&&type=M5");
            hintCode.setSrcr("http://webquoteklinepic.eastmoney.com/GetPic.aspx?nid="+imgcode+"&UnitWidth=-6&imageType=KXL&EF=&Formula=RSI&AT=1&&type=");
            hintCode.setSrcz("http://webquoteklinepic.eastmoney.com/GetPic.aspx?nid="+imgcode+"&UnitWidth=-6&imageType=KXL&EF=&Formula=RSI&AT=1&&type=W");
            hintCode.setSrcy("http://webquoteklinepic.eastmoney.com/GetPic.aspx?nid="+imgcode+"&UnitWidth=-6&imageType=KXL&EF=&Formula=RSI&AT=1&&type=M");

            SharesDetail vo1 = SharesConstan.CODE_DETAIL_MAP.get(hintCode.getCode());

            //提示次数
            List<HintShares> numList = SharesConstan.ALL_INFORM_SHARES_MAP.get(hintCode.getCode());
            if(!CollectionUtils.isEmpty(numList)){
                hintCode.setTsNum(numList.size());
            }
            if(null!=vo1){

                //质押价格
                hintCode.setZyPrice(vo1.getZyprice());
                //行业数据
                hintCode.setSshy(vo1.getSshy());
                //行业消息与新闻
                List<SharesHyzx> sharesHyzxes = SharesConstan.HYZX_MAP.get(hintCode.getSshy());
                hintCode.setSharesHyzxes(sharesHyzxes);

                //资金流向
                SharesZjlx bkzj = SharesConstan.BKZJ_MAP.get(hintCode.getSshy());//板块资金
                hintCode.setBkzj(bkzj);

//                SharesZjlx gnzj = SharesConstan.GNZJ_MAP.get("");//概念资金
                SharesZjlx ggzj = SharesConstan.GGZJ_MAP.get(hintCode.getCode().substring(2));
                hintCode.setGgzj(ggzj);
                //行业市盈率，市净率，个股市盈率，市净率
                SharesHyVsggVo ggsyl = SharesConstan.GGSYL_MAP.get(code);
                hintCode.setGgsyl(ggsyl);
                SharesHyVsggVo hysyl = SharesConstan.HYSYL_MAP.get(hintCode.getSshy());
                hintCode.setHysyl(hysyl);

                //所属概念
                hintCode.setSsgn(vo1.getSsgn());

            }
            //解禁日期
            Long unfastenDay=(long)this.getUnfastenDat(hintCode.getCode()).get("long");
            hintCode.setUnfastenDay(unfastenDay);

            List<String> unfastenList=(List<String>)this.getUnfastenDat(hintCode.getCode()).get("list");
            hintCode.setUnfastenList(unfastenList);

            //并购重组
            List<SharesBgcz> sharesBgczs = SharesConstan.BGCZ_MAP.get(code.substring(2));
            hintCode.setSharesBgczs(sharesBgczs);
            //业绩预告
            List<SharesYjyg> sharesYjygs = SharesConstan.YJYG_MAP.get(code.substring(2));
            hintCode.setSharesYjygs(sharesYjygs);
            //业绩报告
            List<SharesYjbg> sharesYjbgs = SharesConstan.YJBG_MAP.get(code.substring(2));
            hintCode.setSharesYjbgs(sharesYjbgs);
            //最近公告
            List<SharesNotice> notices = SharesConstan.NOTICE_MAP.get(code);
            hintCode.setNotices(notices);
            //股东减持
            List<SharesDirection> sharesDirections = SharesConstan.DIRECTION_MAP.get(code);
            hintCode.setSharesDirections(sharesDirections);
            //股东最新数据
            List<SharesGdnum> sharesGdnums = SharesConstan.GDNUM_MAP.get(code.substring(2));
            hintCode.setSharesGdnums(sharesGdnums);
            //股东变化数据
            List<SharesGdChange> sharesGdChanges = SharesConstan.GDCHANGE_MAP.get(code);
            hintCode.setSharesGdChanges(sharesGdChanges);

            HintShares hintShares = SharesConstan.INFORM_SHARES_MAP.get(hintCode.getCode());
            if(null!=hintShares){
                //峰值类型
                hintCode.setHType(hintShares.getHType());
                //提示次数
                hintCode.setKeepNum(hintShares.getKeepNum());
                hintCode.setKeepTotal(hintShares.getKeepTotal());
                //回撤风险
                hintCode.setZback(hintShares.getZback());
                hintCode.setYback(hintShares.getYback());
                //最新价格
                hintCode.setNewZdf(hintShares.getNewZdf());
                //历史周月涨幅
                if(null!=hintShares.getNewPrice()){
                    hintCode.setNewPrice(hintShares.getNewPrice());
                    this.getzyzf(hintCode);
                }
                //计算季报到当前时间的涨跌幅
                if(!StringUtil.isEmpty(vo1.getZf5())&&null!=hintShares.getNewPrice()){
                    BigDecimal jbzf = MeUtils.calculateTrend(hintCode.getNewPrice().toString(), vo1.getZf5());
                    hintCode.setJbzf(MeUtils.getPercent(jbzf.toString()));
                }
            }
            //最近7天提示过几次
            List<HintShares> hintSharesList = SharesConstan.ALL_INFORM_SHARES_MAP.get(hintCode.getCode());
            if(!CollectionUtils.isEmpty(hintSharesList)){
                hintCode.setTsNum(hintSharesList.size());
            }

            //
            if(null!=vo1){
                //神奇电波
                //计算神奇电波距离当前最小的天数
                if(!StringUtil.isEmpty(vo1.getMagical())){
                    String magical = vo1.getMagical();
                    List<MagicalVo> magicalVos = JSONArray.parseArray(magical, MagicalVo.class);
                    MagicalVo magicalVo = magicalVos.get(magicalVos.size() - 1);
                    String time = magicalVo.getD();
                    String p = magicalVo.getP();//当天的收盘价

                    //计算到目前的涨幅
                    BigDecimal newPrice = hintCode.getNewPrice();
                    if(!StringUtil.isEmpty(p)&&null!=newPrice){
                        BigDecimal dbzfBig = MeUtils.calculateTrend(newPrice.toString(),p );
                        hintCode.setDbzf(MeUtils.getPercent(dbzfBig.toString()));
                    }
                    try {
                        Long timeByStr = DateUtil.getTimeByStr(time);
                        long xc = DateUtil.DaysBetweenByLong(timeByStr, DateUtil.getLongByCurrTime());
                        hintCode.setMagical(xc+"");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            //主营业务
            List<SharesBusiness> sharesBusinesses = SharesConstan.BUSINESS_MAP.get(code);
            hintCode.setBusinesses(sharesBusinesses);

            //最近统计日期
            List<SharesGdnum> gdnums = hintCode.getSharesGdnums();
            if(!CollectionUtils.isEmpty(gdnums)){
                String endDate = gdnums.get(0).getEndDate();
                if(!endDate.contains("2021-09-30")){//不是最近季报统计的
                    //标记
                    hintCode.setTjDate(endDate);
                }
            }
        }
    }

    @Override
    public Map<String,Object> getUnfastenDat(String code) {
        Map<String,Object> map=new HashMap<>();
        //解禁日期
        long juli=9999;
        List<SharesUnfasten> unfastenList = SharesConstan.ALL_UNFASTEN_MAP.get(code);
        List<String>  list=new ArrayList<>();
        if(!CollectionUtils.isEmpty(unfastenList)) {
            for (SharesUnfasten sharesUnfasten : unfastenList) {
                String time = sharesUnfasten.getTime();
                String type = sharesUnfasten.getType();
                StringBuffer sb = new StringBuffer();
                if (time.contains("2021") || time.contains("2022")) {
                    sb.append(time + "---" + type);
                    list.add(sb.toString());
                }
                //相差的天数
                try {
                    long abs = DateUtil.DaysBetweenByLong(DateUtil.getTimeByStr(time.substring(0, 10))
                            , DateUtil.getLongByCurrTime());
                    long abs1 = Math.abs(abs);
                    if (abs1 < juli) {
                        juli = abs1;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            }
        map.put("list",list);
        map.put("long",juli);
        return  map;
        }

    /**
     * 历史周月涨幅
     */
    @Override
    public void getzyzf(HintShares hintShares) {
        String newZdf = hintShares.getNewZdf();//当前的涨跌幅
        BigDecimal divide = new BigDecimal(newZdf).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
        BigDecimal cjBig = new BigDecimal("0.2").subtract(divide);//还有多少上涨空间

        SharesDetail sharesDetail = SharesConstan.CODE_DETAIL_MAP.get(hintShares.getCode());
        if(null==sharesDetail){
            return;
        }
        String zkPrice = sharesDetail.getZkPrice();
        String ykPrice = sharesDetail.getYkPrice();
        if(StringUtil.isEmpty(zkPrice)||StringUtil.isEmpty(ykPrice)){
            return;
        }
        BigDecimal bzzf=new BigDecimal(0);//本周涨幅
        if(!StringUtil.isEmpty(zkPrice)){
            bzzf = MeUtils.calculateTrend(hintShares.getNewPrice().toString(), zkPrice);
        }
        BigDecimal byzf=new BigDecimal(0);//本月涨幅
        if(!StringUtil.isEmpty(ykPrice)){
            byzf = MeUtils.calculateTrend(hintShares.getNewPrice().toString(), ykPrice);
        }

        hintShares.setBzzf(MeUtils.getPercent(bzzf.toString()));
        hintShares.setByzf(MeUtils.getPercent(byzf.toString()));

        int zindex=0;
        int maxzsgin=0;
        String zzf = sharesDetail.getZzf();
        if(!StringUtil.isEmpty(zzf)){
            List<SharesZdfVo> zdfVos = JSONArray.parseArray(zzf, SharesZdfVo.class);
            if(!CollectionUtils.isEmpty(zdfVos)){
                SharesZdfVo sharesZdfVo = zdfVos.get(zdfVos.size()-1);

                //本周涨幅-上次上涨周=差距
                BigDecimal zcj = bzzf.subtract(new BigDecimal(sharesZdfVo.getZdf()));
                hintShares.setZzdfsub(MeUtils.getPercent(zcj.toString()));

                BigDecimal maxSub=new BigDecimal("999");
                List<SharesZdfCopyVo> voList=new ArrayList<>();
                for (SharesZdfVo zdfVo : zdfVos) {
                    SharesZdfCopyVo sharesZdfCopyVo = new SharesZdfCopyVo();
                    String zdf = zdfVo.getZdf();


                    BigDecimal subtract = bzzf.subtract(new BigDecimal(zdf));
                    if(subtract.compareTo(new BigDecimal("0"))==1){
                        zindex++;
                    }

                    if((subtract.add(cjBig)).compareTo(new BigDecimal("0"))==1){
                        maxzsgin++;
                    }

                    if(subtract.compareTo(maxSub)==-1){
                        maxSub=subtract;
                    }

                    sharesZdfCopyVo.setD(zdfVo.getD());
                    sharesZdfCopyVo.setNewzdf(MeUtils.getPercent(bzzf.toString()));
                    sharesZdfCopyVo.setZdf(MeUtils.getPercent(zdf));
                    sharesZdfCopyVo.setSub(MeUtils.getPercent(subtract.toString()));
                    voList.add(sharesZdfCopyVo);
                }
                //大于本周涨幅
                hintShares.setZzfsign(zindex);//标记本周涨幅
                hintShares.setMaxzsgin(maxzsgin);
                hintShares.setMaxzzdf(MeUtils.getPercent(maxSub.toString()));
                hintShares.setZvoList(voList);
            }
        }

        int yindex=0;
        int maxysgin=0;
        String yzf = sharesDetail.getYzf();
        if(!StringUtil.isEmpty(yzf)){
            List<SharesZdfVo> zdfVos = JSONArray.parseArray(yzf, SharesZdfVo.class);
            if(!CollectionUtils.isEmpty(zdfVos)){
                SharesZdfVo sharesZdfVo = zdfVos.get(zdfVos.size()-1);

                //本月涨幅-上次上涨月=差距
                BigDecimal zcj = byzf.subtract(new BigDecimal(sharesZdfVo.getZdf()));
                hintShares.setYzdfsub(MeUtils.getPercent(zcj.toString()));

                BigDecimal maxSub=new BigDecimal("999");
                List<SharesZdfCopyVo> voList=new ArrayList<>();
                for (SharesZdfVo zdfVo : zdfVos) {
                    SharesZdfCopyVo sharesZdfCopyVo = new SharesZdfCopyVo();
                    String zdf = zdfVo.getZdf();
                    BigDecimal subtract = byzf.subtract(new BigDecimal(zdf));

                    if(subtract.compareTo(new BigDecimal("0"))==1){
                        yindex++;
                    }

                    if((subtract.add(cjBig)).compareTo(new BigDecimal("0"))==1){
                        maxysgin++;
                    }

                    if(subtract.compareTo(maxSub)==-1){
                        maxSub=subtract;
                    }

                    sharesZdfCopyVo.setD(zdfVo.getD());
                    sharesZdfCopyVo.setZdf(MeUtils.getPercent(zdf));
                    sharesZdfCopyVo.setNewzdf(MeUtils.getPercent(byzf.toString()));
                    sharesZdfCopyVo.setSub(MeUtils.getPercent(subtract.toString()));
                    voList.add(sharesZdfCopyVo);
                }
                hintShares.setYzfsign(yindex);//标记本周涨幅
                hintShares.setMaxysgin(maxysgin);
                hintShares.setMaxyzdf(MeUtils.getPercent(maxSub.toString()));
                hintShares.setYvoList(voList);
            }
        }
    }

    /**
     * 大涨股相关股
     * @return
     */
    @Override
    public Result highzdf(HttpServletRequest request) {

//        getInit();
        //提示股
        Map<String,List<SharesData>> map=new HashMap<>();
        Map<String,Map<String,SharesHintVo>> hMap=new HashMap<>();

        for (String key : SharesConstan.INFORM_SHARES_MAP.keySet()) {//通知过的股
            HintShares hintShares = SharesConstan.INFORM_SHARES_MAP.get(key);
            String newZdf = hintShares.getNewZdf();
            String name = hintShares.getName();
            if(new BigDecimal(newZdf).compareTo(new BigDecimal(10))==1){
                List<SharesData> vos = SharesConstan.HIGT_SHARES_MAP.get(key);//跟涨股有那些
                Map<String,SharesHintVo> iMap=new HashMap<>();
                if(!CollectionUtils.isEmpty(vos)){
                    for (SharesData vo : vos) {
                        String voName = vo.getName();
                        String code = vo.getCode();
//                    Integer integer = iMap.get(code.trim()+"~"+voName);
                        SharesHintVo hintVo = iMap.get(code.trim());
                        if(null==hintVo){
                            SharesHintVo voHint=new SharesHintVo();
                            voHint.setCode(code);
                            voHint.setNum(1);
                            iMap.put(code.trim(),voHint);
                        }else{
                            hintVo.setNum(hintVo.getNum()+1);
                            iMap.put(code.trim(),hintVo);
                        }
                    }
                    hMap.put(name,iMap);
                }
            }
        }
        Map<String,Integer> codeNum=new HashMap<>();
        //一共出现的次数
        for (String name : hMap.keySet()) {
//            Map<String, Integer> integerMap = hMap.get(name);
            Map<String, SharesHintVo> stringSharesHintVoMap = hMap.get(name);
            for (String codekey : stringSharesHintVoMap.keySet()) {
                SharesHintVo hintVo = stringSharesHintVoMap.get(codekey);
                String code = hintVo.getCode();
                Integer num = hintVo.getNum();

                Integer integer = codeNum.get(code);
                if(null==integer){
                    codeNum.put(code,num);
                }else{
                    codeNum.put(code,integer+num);
                }
            }
//            for (String key : integerMap.keySet()) {
//                Integer intNum = integerMap.get(key);
//                String[] split = key.split("~");
//                Integer integer = codeNum.get(split[0]);
//                if(null==integer){
//                    codeNum.put(split[0],intNum);
//                }else{
//                    codeNum.put(split[0],integer+intNum);
//                }
//            }
        }

        List<SharesDetail> sharesDetails=new ArrayList<>();
        //排序
        for (String code : codeNum.keySet()) {
            Integer integer = codeNum.get(code);
            if(integer>6){
                SharesDetail sharesDetail = SharesConstan.CODE_DETAIL_MAP.get(code);
                HintShares hintShares = SharesConstan.INFORM_SHARES_MAP.get(code);
                if(null!=hintShares){
                    int tsOrder = hintShares.getTsOrder();
                    int asorder = hintShares.getAsorder();
                    sharesDetail.setHintType("1");
                    sharesDetail.setNum(integer);
                    sharesDetail.setTsOrder(tsOrder);
                    sharesDetail.setAsorder(asorder);
                    sharesDetail.setZf10(hintShares.getNewZdf());
                    sharesDetail.setZf20(hintShares.getTsZdf());
                    sharesDetails.add(sharesDetail);
                }else{
                    sharesDetail.setHintType("0");
                    sharesDetail.setNum(integer);
                    sharesDetails.add(sharesDetail);
                }
            }
        }
        if(!CollectionUtils.isEmpty(sharesDetails)){
            List<SharesDetail> collect = sharesDetails.stream().sorted(Comparator.comparing(SharesDetail::getNum).reversed()).collect(Collectors.toList());
            return Result.success(collect);
        }
        return Result.success(sharesDetails);
    }

    private void getInit() {

        //行业信息
        SharesConstan.CODE_DETAIL_MAP.clear();
        SharesConstan.CODE_LIST.clear();
        SharesConstan.GZ_SHARES_MAP.clear();
        SharesConstan.GZ_HINTSHARES_MAP.clear();
        Wrapper<SharesDetail> wr=new EntityWrapper<>();
        wr.eq("status",88);
//        wr.eq("status",SharesConstan.ALL_SHARES);
        SharesConstan.CODE_LIST= sharesDetailService.selectList(wr);
        for (SharesDetail sharesDetail : SharesConstan.CODE_LIST) {
            String code = sharesDetail.getCode();
            SharesConstan.CODE_DETAIL_MAP.put(code,sharesDetail);
            String type = sharesDetail.getType();
            if(!StringUtil.isEmpty(type)&&SharesConstan.GZ.equals(type)){
                SharesConstan.GZ_SHARES_MAP.put(code,sharesDetail);
            }
        }

        SharesConstan.ORDERINT=0;
        SharesConstan.ASORDERINT=0;
        Wrapper<HintShares> wrhs=new EntityWrapper<>();
        wrhs.orderBy("id");
        wrhs.gt("time",DateUtil.getYMDByDaysAgo(7));
        List<HintShares> hintShares = hintSharesService.selectList(wrhs);
        SharesConstan.ALL_INFORM_SHARES_MAP.clear();
        SharesConstan.INFORM_SHARES_MAP.clear();
        SharesConstan.HI_SHARES_MAP.clear();
        SharesConstan.HI_HINTSHARES_MAP.clear();



        for (HintShares hintShare : hintShares) {
            List<HintShares> hList = SharesConstan.ALL_INFORM_SHARES_MAP.get(hintShare.getCode());
            if(CollectionUtils.isEmpty(hList)){
                List<HintShares> vList=new ArrayList<>();
                vList.add(hintShare);
                //提示次数
                SharesConstan.ALL_INFORM_SHARES_MAP.put(hintShare.getCode(),vList);
            }else{
                hList.add(hintShare);
            }
            //今天已经提示过的股
            if(DateUtil.getDate_yyyyMMdd().equals(hintShare.getTime())){
                hintShare.setTsOrder(SharesConstan.ORDERINT++);
                SharesConstan.INFORM_SHARES_MAP.put(hintShare.getCode(),hintShare);
            }
            //最近7天涨幅大于10的股
            String newZdf = hintShare.getNewZdf();
            if(!StringUtil.isEmpty(newZdf)&&new BigDecimal(newZdf).compareTo(new BigDecimal(10))==1){
                String code = hintShare.getCode();
                SharesDetail sharesDetail = SharesConstan.CODE_DETAIL_MAP.get(code);
                if(null!=sharesDetail){
                    sharesDetail.setType(SharesConstan.HI);
                    SharesConstan.HI_SHARES_MAP.put(code,sharesDetail);
                }
            }
        }

        sharesDataService.getZdfShares();//初始化
    }


    private void doMap(Map<String, Integer> map, String time) {
        Integer integer = map.get(time);
        if(null==integer){
            map.put(time,1);
        }else{
            map.put(time,integer+1);
        }
    }

}
